use std::{any::Any, collections::HashMap, sync::Arc};

use mf_core::{config::ForgeConfig, event::{Event, EventHandler}, middleware::MiddlewareStack, types::Extensions, Content};
use price_rules::loader::RulesLoaderExt;

use super::{
    BootstrapError, ProjectProfile,
    artifacts::{BootstrapArtifacts, DataSourceMap, ExtraStore},
};

/// 引导阶段上下文
///
/// 每一个阶段都会拿到该上下文以读取项目画像或写入阶段产物。
/// 全流程结束后上下文会被收敛为 BootstrapArtifacts，再交由上层组装运行时组件。
///
/// # 重构后的设计
///
/// 支持收集事件处理器、中间件和 Forge 配置，使 Bootstrap 成为完整的应用初始化系统。
pub struct BootstrapContext {
    profile: ProjectProfile,
    extensions: Vec<Extensions>,
    metadata: HashMap<String, String>,
    rule_loader: Option<Arc<dyn RulesLoaderExt>>,
    data_sources: DataSourceMap,
    extras: ExtraStore,

    /// 事件处理器列表
    event_handlers: Vec<Arc<dyn EventHandler<Event> + Send + Sync>>,

    /// 中间件栈（可选）
    middleware_stack: Option<MiddlewareStack>,

    /// Forge 性能配置（可选）
    forge_config: Option<ForgeConfig>,
    content:Content
}

impl BootstrapContext {
    /// 创建新的上下文
    pub fn new(profile: ProjectProfile) -> Self {
        Self {
            profile,
            extensions: Vec::new(),
            metadata: HashMap::new(),
            rule_loader: None,
            data_sources: HashMap::new(),
            extras: ExtraStore::new(),
            event_handlers: Vec::new(),
            middleware_stack: None,
            forge_config: None,
            content:Content::None
        }
    }

    /// 读取项目画像
    pub fn profile(&self) -> &ProjectProfile {
        &self.profile
    }

    /// 追加扩展节点/插件定义
    pub fn push_extensions<I>(
        &mut self,
        items: I,
    ) where
        I: IntoIterator<Item = Extensions>,
    {
        self.extensions.extend(items);
    }

    /// 获取已收集的扩展
    pub fn extensions(&self) -> &[Extensions] {
        &self.extensions
    }

    /// 设置规则加载器（通常在规则阶段完成）
    pub fn set_rule_loader(
        &mut self,
        loader: Arc<dyn RulesLoaderExt>,
    ) {
        self.rule_loader = Some(loader);
    }

    /// 获取规则加载器
    pub fn rule_loader(&self) -> Option<&Arc<dyn RulesLoaderExt>> {
        self.rule_loader.as_ref()
    }

    /// 获取元数据的可变引用，方便阶段直接写入
    pub fn metadata_mut(&mut self) -> &mut HashMap<String, String> {
        &mut self.metadata
    }

    /// 获取元数据
    pub fn metadata(&self) -> &HashMap<String, String> {
        &self.metadata
    }

    /// 注册共享数据源（外部传入 Arc）
    pub fn register_data_source<T>(
        &mut self,
        key: impl Into<String>,
        value: Arc<T>,
    ) where
        T: Any + Send + Sync + 'static,
    {
        self.data_sources.insert(key.into(), value);
    }

    /// 注册共享数据源（直接传值，由上下文包装成 Arc）
    pub fn register_data_source_owned<T>(
        &mut self,
        key: impl Into<String>,
        value: T,
    ) where
        T: Any + Send + Sync + 'static,
    {
        self.data_sources.insert(key.into(), Arc::new(value));
    }

    /// 读取所有数据源
    pub fn data_sources(&self) -> &DataSourceMap {
        &self.data_sources
    }

    /// 写入额外产物
    pub fn insert_extra<T>(
        &mut self,
        value: T,
    ) where
        T: Any + Send + Sync + 'static,
    {
        self.extras.insert(value);
    }

    /// 读取额外产物
    pub fn extra<T>(&self) -> Option<&T>
    where
        T: Any + Send + Sync + 'static,
    {
        self.extras.get::<T>()
    }

    /// 添加事件处理器
    pub fn add_event_handler(
        &mut self,
        handler: Arc<dyn EventHandler<Event> + Send + Sync>,
    ) {
        self.event_handlers.push(handler);
    }

    /// 获取事件处理器列表
    pub fn event_handlers(&self) -> &[Arc<dyn EventHandler<Event> + Send + Sync>] {
        &self.event_handlers
    }

    /// 设置中间件栈
    pub fn set_middleware_stack(
        &mut self,
        stack: MiddlewareStack,
    ) {
        self.middleware_stack = Some(stack);
    }

    /// 获取中间件栈
    pub fn middleware_stack(&self) -> Option<&MiddlewareStack> {
        self.middleware_stack.as_ref()
    }

    /// 设置 Forge 配置
    pub fn set_forge_config(
        &mut self,
        config: ForgeConfig,
    ) {
        self.forge_config = Some(config);
    }

    /// 获取 Forge 配置
    pub fn forge_config(&self) -> Option<&ForgeConfig> {
        self.forge_config.as_ref()
    }

    /// 将上下文收敛为最终产物
    pub fn into_artifacts(self) -> Result<BootstrapArtifacts, BootstrapError> {
        let rule_loader = self.rule_loader.ok_or(BootstrapError::MissingRuleLoader)?;

        Ok(BootstrapArtifacts::new(
            self.profile,
            self.extensions,
            self.metadata,
            rule_loader,
            self.data_sources,
            self.extras.into_inner(),
            self.event_handlers,
            self.middleware_stack,
            self.forge_config,
            self.content
        ))
    }
}
